package com.hhkj.admin.order.common.component.validator;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import com.hhkj.admin.course.domain.Course;
import com.hhkj.admin.course.domain.CourseBankType;
import com.hhkj.admin.course.domain.CoursePriceConf;
import com.hhkj.admin.order.common.cont.OrderRefundConst;
import com.hhkj.admin.order.common.exception.InvalidOrderItemException;
import com.hhkj.admin.order.common.exception.StudentEnrolledException;
import com.hhkj.admin.order.domain.OrderItem;
import com.hhkj.admin.student.domain.StudentCourse;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

public class OrderItemValidator {

    private static final Logger logger = LoggerFactory.getLogger(OrderItemValidator.class);

    /**
     * 校验名字是否合规
     * @param orderItem 订单内的学员信息
     * @return 返回名字是否合规
     */
    public static boolean isValidName(OrderItem orderItem) {
        String name = orderItem.getName();
        if (StringUtils.isBlank(name)) {
            throw new InvalidOrderItemException("学员姓名不能为空");
        }
        return true;
    }

    /**
     * 校验身份证号是否合规
     * @param orderItem 订单内的学员信息
     * @return 返回是否合规
     */
    public static boolean isValidIdCard(OrderItem orderItem) {
        String idCard = orderItem.getIdCard();
        if (StringUtils.isBlank(idCard)) {
            throw new InvalidOrderItemException("身份证号不能为空");
        }
        if (IdcardUtil.isValidCard(idCard) == false) {
            throw new InvalidOrderItemException("身份证号格式错误");
        }
        return true;
    }

    /**
     * 校验手机号是否合规
     * @param orderItem 订单内的学员信息
     * @return 返回是否合规
     */
    public static boolean isValidPhone(OrderItem orderItem) {
        String phone = orderItem.getPhone();
        if (StringUtils.isBlank(phone)) {
            return true;
        }
        if (PhoneUtil.isPhone(phone) == false) {
            throw new InvalidOrderItemException("手机号格式错误");
        }
        return true;
    }

    /**
     * 校验科目名称是否合法，以及该名字的科目是否存在
     * @param orderItem 订单内的学员信息
     * @return 如果合法并且存在，返回课程id
     */
    public static Long isValidCourse(OrderItem orderItem, List<? extends Course> courseList) {
        String courseName = orderItem.getCourseName();
        if (StringUtils.isBlank(courseName)) {
            throw new InvalidOrderItemException("科目不能为空");
        }
        if (ObjectUtil.isEmpty(courseList)) {
            throw new InvalidOrderItemException("科目不存在，请联系管理员或切换科目");
        }
        if (courseList.size() > 1) {
            throw new InvalidOrderItemException("该科目为重名科目，请联系管理员或切换科目");
        }
        Course course = CollectionUtil.getFirst(courseList);
        if (ObjectUtil.isEmpty(course)) {
            throw new InvalidOrderItemException("科目不存在，请联系管理员或切换科目");
        }
        return course.getId();
    }

    /**
     * 校验指定科目的默认题库是否存在，是否合法
     * @param list 科默认题库列表
     * @return 返回是否存在，是否合法
     */
    public static Long isValidDefaultCourseBank(List<CourseBankType> list) {
        if (ObjectUtil.isEmpty(list) || list.size() < 1) {
            throw new InvalidOrderItemException("该科目不存在默认题库，请联系管理员或切换科目");
        }
        if (list.size() > 1) {
            throw new InvalidOrderItemException("该科目存在多个默认题库，请联系管理员或切换科目");
        }
        return CollectionUtil.getFirst(list).getId();
    }

    /**
     * 校验购买的价格和天数是否和系统中配置的一致
     * @param orderItem 订单内的学员信息
     * @param coursePriceConfList 该科目的所有价格列表
     * @return 返回是否一致
     */
    public static Long isValidDayAmountAndPrice(OrderItem orderItem, List<CoursePriceConf> coursePriceConfList) {
        Integer orderItemDayAmount = orderItem.getDayAmount();
        if (ObjectUtil.isEmpty(orderItemDayAmount)) {
            throw new InvalidOrderItemException("账号期限不能为空");
        }
        BigDecimal orderItemPrice = orderItem.getPrice();
        if (ObjectUtil.isEmpty(orderItemPrice)) {
            throw new InvalidOrderItemException("学员单价不能为空");
        }
        if (CollectionUtil.isEmpty(coursePriceConfList)) {
            throw new InvalidOrderItemException("科目并未指定价格，请联系管理员或切换科目");
        }
        int j = 0;
        for (; j < coursePriceConfList.size(); j++) {
            CoursePriceConf coursePriceConf = coursePriceConfList.get(j);
            Integer dayAmount = coursePriceConf.getDayAmount();
            BigDecimal price = coursePriceConf.getPrice();
            if(dayAmount.compareTo(orderItemDayAmount) == 0 && price.compareTo(orderItemPrice) == 0) {
                return coursePriceConf.getId();
            }
        }
        throw new InvalidOrderItemException("科目的学员单价和账号期限不正确，请填写正确的课程价格和帐号期限");
    }

    /**
     * 校验学员是否 还未报名
     * @param courseId 科目id
     * @param studentCourseList 该学员正在学习的学员科目信息
     * @return true--还未报名 false-已经报名过该科目了
     */
    public static boolean isStudentNotEnroll(List<StudentCourse> studentCourseList, Long courseId) {
        if (ObjectUtil.isEmpty(studentCourseList)) {
            return true;
        }
        List<Long> courseIdList = studentCourseList.stream().map(StudentCourse::getCourseId).collect(Collectors.toList());
        return isStudentNotEnroll(courseId, courseIdList);
    }

    /**
     * 校验学员是否 还未报名
     * @param courseId 科目id
     * @param courseIdList 该学员正在学习的科目id列表
     * @return true--还未报名 false-已经报名过该科目了
     */
    public static boolean isStudentNotEnroll(Long courseId, List<Long> courseIdList) {
        if (ObjectUtil.isEmpty(courseIdList)) {
            return true;
        }
        if (courseIdList.contains(courseId)) {
            throw new StudentEnrolledException("该学员已经报名该科目，请勿重新报名");
        }
        return true;
    }

    /**
     * 校验学员是否与系统中存在的学员名字不一样
     * @param target 目标学员名称
     * @param source 系统中存在的学员名称
     * @return true--还未报名 false-已经报名过该科目了
     */
    public static boolean isDifferentName(String target, String source) {
        if (StringUtils.isBlank(source)) {
            logger.warn("传入的参数中，系统中原学员名称为空");
            return false;
        }
        if(ObjectUtil.equal(target, source)) {
            throw new InvalidOrderItemException("系统内存在身份证相同姓名不同的学员，请联系客服核对");
        }
        return true;
    }

    /**
     * 校验子订单是否都来源于同一个订单
     * @param orderItemList 子订单列表
     * @return
     */
    public static boolean isSameOrder(List<OrderItem> orderItemList) {
        if (ObjectUtil.isEmpty(orderItemList)) {
            logger.warn("传入的参数中，子订单列表为空");
            return false;
        }
        OrderItem orderItem = CollectionUtil.getFirst(orderItemList);
        Long orderId = orderItem.getOrderId();
        for (int i = 0; i < orderItemList.size(); i++) {
            if (orderItemList.get(i).equals(orderId) == false) {
                throw new InvalidOrderItemException("子订单来自于不同的订单，请检查");
            }
        }
        return true;
    }

    /**
     * 校验子订单是否来源于这个订单
     * @param orderItem 子订单信息
     * @param orderId 订单id
     * @return
     */
    public static boolean isBelongThisOrder(OrderItem orderItem, Long orderId) {
        if (orderItem.getOrderId().equals(orderId) == false) {
            throw new InvalidOrderItemException("该子订单并非来源自本订单");
        }
        return true;
    }

    /**
     * 子订单的状态是否处于可退款的状态
     * @param orderItem
     * @return
     */
    public static boolean isRefundableStatus(OrderItem orderItem) {
        if(ObjectUtil.isEmpty(orderItem)) {
            throw new InvalidOrderItemException("子订单为空，请检查");
        }
        String refundStatusCode = orderItem.getRefundStatusCode();
        if (OrderRefundConst.StatusEnum.REFUNDING.getCode().equals(refundStatusCode)) {
            throw new InvalidOrderItemException("该子订单正在退款，无法再次退款");
        } else if (OrderRefundConst.StatusEnum.SUCCESS.getCode().equals(refundStatusCode)) {
            throw new InvalidOrderItemException("该子订单已退款完成，无法再次退款");
        }
        return true;
    }

    /**
     * 批量判断子订单是否都是处于可退款的状态
     * @param orderItemList 子订单列表
     * @return
     */
    public static boolean isAllRefundable(List<OrderItem> orderItemList) {
        if(ObjectUtil.isEmpty(orderItemList)) {
            throw new GlobalException("子订单为空，请检查");
        }
        orderItemList.forEach(orderItem -> isRefundableStatus(orderItem));
        return true;
    }

}
